/*
 * @Author: lujing
 * @Date: 2024-06-13 09:29:14
 * @LastEditTime: 2024-06-24 14:32:51
 * @FilePath: \workspace\fy\aiDigitalPerson\dipu-xjy-meta-digital-person\src\pages\digitalHuman\Home-tb.tsx
 */
import { Box, Stack, Grid } from '@mui/material';
import DigitalBg from 'assets/digital-bg.png'
import Human from 'components/digital/HumanContainer'
import ChatBox from 'components/digital/ChatContainer'
import zantingIcon from 'assets/zanting-active.png';
import pauseIcon from 'assets/pause_02.png';
import {promtStringState, isRenderingState, loadingState, voicingState, sessionState, messagesState, IMessage } from 'state/chat';
import { useRecoilState, useSetRecoilState, useRecoilValue } from 'recoil';
import { useEffect } from 'react';
import { clientState } from 'state/client';
import { v4 as uuidv4 } from 'uuid'; 
import {digitalIframeUrl} from 'api/index';
import { toast } from 'react-hot-toast';


export default function Home() {
    const queryString = window.location.search;
    const urlParams = new URLSearchParams(queryString);
    const shuziren = urlParams.get('shuziren') ?? digitalIframeUrl;
    const setIsRendering = useSetRecoilState(isRenderingState);
    const setLoading = useSetRecoilState(loadingState);
    const loading = useRecoilValue(loadingState)
    const setVoicing = useSetRecoilState(voicingState);
    const session = useRecoilValue(sessionState);
    const promtString = useRecoilValue(promtStringState);
    const [messages, setMessages] = useRecoilState(messagesState)

    const handleStopRendering = () => {
        setLoading(false);
        setIsRendering(false);
        setVoicing('default')
        // 触发数字人讲话[停止说话]
        client.setAISay('','task_stop')
        // const lastIndex = messages.findLastIndex(obj => obj.parentId === null);
        // let message: IMessage
        // 如果找到符合条件的对象，则为其添加show: true属性
        // if (lastIndex !== -1) {
        //     message = messages[lastIndex]
        //     message.stopRendering = true
        //     setMessages((oldMessages) => {
        //        return [
        //             ...oldMessages.slice(0, lastIndex),
        //             message,
        //             ...oldMessages.slice(lastIndex + 1)
        //           ]
        //     })
        // }
        // session?.socket.emit('stop');
        session?.socket.emit('stop');

    };
    
    const client = useRecoilValue(clientState);

    // 一些临时数据
    let dealResultStr = "";//解析后的字符串集合

    
  
    // 监听是否收到声音
    useEffect(()=>{
        if(promtString){
            // console.log('==>',promtString)
            // if(loading){
            // 打断上一个问题
            // handleStopRendering();
           

            // setTimeout(()=>{
                setIsRendering(true)
                // 展示一条问题
                const message: IMessage = {
                    id: uuidv4(),
                    author: '访客',
                    authorIsUser: true,
                    content: promtString,
                    createdAt: new Date().toISOString()
                };
                // 添加一条消息
                setMessages((m)=>[...m,message])
                setLoading(true)
                getResult(promtString)

            // },1000)

               

            // }
           
        }
       
    },[promtString])

    useEffect(()=>{
        console.log('数字人页面打开！！！')
        // 触发数字人说开场白
        client.setAISay('你好，我是新建元数字员工元晓宇，请问有什么需要帮助的吗？','stream_token')
        // todo
    },[])
    async function  getResult(promtString:string){
        console.log('getResult')
        // 发起请求之前，清空答案变量；生成一个消息
        dealResultStr = "";
        let allToken = "";//全部token
         // 生成一个消息模板
         let  messageId = uuidv4();
         let  message1: IMessage = {
            id: messageId,
            author: '元晓宇',
            authorIsUser: false,
            content: '',
            createdAt: new Date().toISOString()
         };
        
        await client.getLLMData(promtString,(done,token)=>{
            // console.log('一次拉去数据==='+token)
            if(done){
              // 回调一次就要解析一次
              dealResult(allToken,messageId,message1);
                // 触发数字人结束讲话
            //   client.setAISay('','stream_end')
                  // stream_start：开始推送数据
                  // stream_token：正在推送数据
                  // stream_end：推送数据正常结束
                  // task_stop：用户打断当前交互流程
                
            }else{
               

            }
            allToken+=token;
            
        })

    }

    const dealResult = (token:string,messageId:string,messageTemplate:IMessage)=>{
            let currResult = ""
            // 从字符串结果中获得对象
            let resultList =  dealStr2Arr(token)
            // 得到正确的答案
            resultList.forEach(item=>{
                if(item.path=='/streamed_output/-'){
                    currResult+=item.value;
                }
            })
            dealResultStr += currResult

            // 每次拉取的数据，有答案内容，就要播报和展示
            if(currResult){
              // 触发数字人讲话
              setVoicing('event_vad_begin')
              let now_time = getCurrentDateTime();
              client.setAISay(currResult,'stream_token')
              console.log('机器人说话时间：'+now_time + '，内容：'+currResult)
              setMessages((m)=>{
                let oldLastMsg = m[m.length-1];
                console.log('oldLastMsg.id=',oldLastMsg.id)
                // 此消息已经存在，继续追加内容
                if(oldLastMsg.id == messageId){
                    console.log('追加'+dealResultStr)
                    return[...m.slice(0,m.length-1),{...oldLastMsg,content:dealResultStr}]
                // 需要新创建消息
                }else{
                    console.log('新增'+dealResultStr)
                    let tempMsg = {...messageTemplate,content:dealResultStr}
                    return [...m,tempMsg]
                }
              })

            }
              
    }
    const  dealStr2Arr = (token:string)=>{
            // 正则表达式匹配
            const regex = /data: (\{(?:[^{}]|(?:\{[^{}]*\}))*\})/g;
            let match;
            const result = [];

            // 循环匹配字符串中的所有对象并存入数组
            while ((match = regex.exec(token)) !== null) {
                const jsonData = match[1];
                try {
                    const parsedData = JSON.parse(jsonData);
                    // 判断是否包含"value"和"path"字段
                    if (parsedData.ops && Array.isArray(parsedData.ops)) {
                    for (const op of parsedData.ops) {
                        if (op.op === "add" && op.path && op.value) {
                        result.push({ path: op.path, value: op.value });
                        }
                    }
                    }
                } catch (error) {
                    debugger;
                    console.error('解析 JSON 出错:', error);
                }
            }

            return result;

    }

    function getCurrentDateTime() {
        const now = new Date();
        const year = now.getFullYear();
        const month = (now.getMonth() + 1).toString().padStart(2, '0');
        const day = now.getDate().toString().padStart(2, '0');
        const hours = now.getHours().toString().padStart(2, '0');
        const minutes = now.getMinutes().toString().padStart(2, '0');
        const seconds = now.getSeconds().toString().padStart(2, '0');
        return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
      }


    return (
        <Box sx={{margin:'0 auto',position:'relative',width:'1080px',height:'1920px'}}>
            <Box sx={{
                width:'100%',height:'100%',
                overflow: 'hidden',
            }}>
                {/* <Human></Human> */}
                <iframe style={{
                     width: '100%',
                     height: '100%',
                }} src={shuziren} allowFullScreen></iframe>
                {/* <img src={DigitalBg} /> */}
            </Box>
            <Box sx={{
                position: 'absolute',
                top: '60%',
                right: 0,
                left:0,
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                minWidth: '700px',
                width: '100%',
                height:'40%',
                
                // flex: 2,
                zIndex: 999999
            }}>
                <ChatBox></ChatBox>
            </Box>
            <Box sx={{
                 position: 'absolute',
                 bottom: '2px',
                 right: '50px',
                 cursor: 'pointer',
                 zIndex: 999999
            }}>
                <img onClick={handleStopRendering}  src={pauseIcon}/>
                
            </Box>
        </Box>
    );
}
